﻿
using Itech_Run.Application.Contracts.Shared.Dto;
using Itech_Run.Application.Shared;
using Itech_Run.Sys.Application.Contracts.Dto;
using Itech_Run.Sys.Application.Contracts.Service;
using Itech_Run.Sys.Domain.Entity;
using System.Linq.Expressions;
using System.Linq.Dynamic.Core;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
using Itech_Run.Sys.Domain.Manager;

namespace Itech_Run.Sys.Application.Service
{
    public class SysRoleService : BaseApplicationService<Sys_Role>, ISysRoleService
    {
        private readonly IRepository<Sys_Role, string> _sysRoleRepository;
        private readonly Sys_RoleManager _sysRoleManager;

        public SysRoleService(IRepository<Sys_Role, string> sysRoleRepository, Sys_RoleManager sysRoleManager)
        {
            _sysRoleRepository = sysRoleRepository;
            _sysRoleManager = sysRoleManager;
        }

        public async Task DeleteAsync(string id)
        {
            try
            {
                var entity = await _sysRoleRepository.GetAsync(id, includeDetails: true);
                await _sysRoleRepository.DeleteAsync(entity);
            }
            catch { }
        }

        public async Task<SysRoleDto> GetAsync(string id)
        {
            var entity = await _sysRoleRepository.GetAsync(id, includeDetails: true);
            return ObjectMapper.Map<Sys_Role, SysRoleDto>(entity);
        }

        public async Task<PagedResultDto<SysRoleDto>> GetListAsync(SysRoleListDto listDto)
        {
            if (string.IsNullOrEmpty(listDto.Sorting)) listDto.Sorting = "Name asc";
            Expression<Func<Sys_Role, bool>> curExpression = s => true;
            if (!string.IsNullOrEmpty(listDto.Name))
                curExpression = curExpression.And(s => s.Name.Contains(listDto.Name));
            if (listDto.IsActive != null)
                curExpression = curExpression.And(s => s.IsActive == listDto.IsActive);

            var query = (await _sysRoleRepository.WithDetailsAsync()).WhereIf(true, curExpression).OrderBy(listDto.Sorting);
            var items = ObjectMapper.Map<List<Sys_Role>, List<SysRoleDto>>(query.PageBy(listDto.SkipCount, listDto.MaxResultCount).ToList());

            return new PagedResultDto<SysRoleDto>(query.Count(), items);
        }

        public async Task<List<KeyValueDto>> GetListKeyValueAsync()
        {
            var query =
                from r in await _sysRoleRepository.GetQueryableAsync()
                where r.IsActive == true
                orderby r.Name ascending
                select new KeyValueDto
                {
                    Key = r.Id,
                    Value = r.Name
                };

            return query.ToList();
        }

        public async Task<SysRoleDto> InsertAsync(SysRoleCreateDto dto, string operateUser)
        {
            var entity = ObjectMapper.Map<SysRoleCreateDto, Sys_Role>(dto);
            await _sysRoleManager.Check_UniqueAsync(entity);
            SetInsertBy(entity, operateUser);
            if (dto.ModuleButtonList.Count > 0)
            {
                List<string> moduleList = dto.ModuleButtonList.Select(s => s.ModuleId).ToList();
                List<KeyValuePair<string, string>> moduleButtonKeyValueList = new List<KeyValuePair<string, string>>();
                dto.ModuleButtonList.ForEach(item =>
                {
                    item.ButtonList.ForEach(buttonItem =>
                    {
                        moduleButtonKeyValueList.Add(new KeyValuePair<string, string>(item.ModuleId, buttonItem));
                    });
                });
                entity.AllocateRoleModule(moduleList);
                entity.AllocateRoleModuleButton(moduleButtonKeyValueList);
            }
            var result = await _sysRoleRepository.InsertAsync(entity);
            return ObjectMapper.Map<Sys_Role, SysRoleDto>(result);
        }

        public async Task<SysRoleDto> UpdateAsync(SysRoleUpdateDto dto, string operateUser)
        {
            var entity = await _sysRoleRepository.GetAsync(dto.Id, includeDetails: true);
            ObjectMapper.Map(dto, entity);
            await _sysRoleManager.Check_UniqueAsync(entity);
            SetUpdateBy(entity, operateUser);
            #region 设置模块、模块按钮
            List<string> moduleList = dto.ModuleButtonList.Select(s => s.ModuleId).ToList();
            List<KeyValuePair<string, string>> moduleButtonKeyValueList = new List<KeyValuePair<string, string>>();
            dto.ModuleButtonList.ForEach(item =>
            {
                item.ButtonList.ForEach(buttonItem =>
                {
                    moduleButtonKeyValueList.Add(new KeyValuePair<string, string>(item.ModuleId, buttonItem));
                });
            });
            entity.AllocateRoleModule(moduleList);
            entity.AllocateRoleModuleButton(moduleButtonKeyValueList);
            #endregion
            var result = await _sysRoleRepository.UpdateAsync(entity);
            return ObjectMapper.Map<Sys_Role, SysRoleDto>(result);
        }
    }
}
